import type { RouteRecordRaw } from 'vue-router'
import type { PermissionType } from '@/services/types'

/**
 * @description 获取localStorage
 * @param {string} key Storage名称
 * @returns {string} 返回处理后的Storage值
 */
export function localGet(key: string) {
  const value = window.localStorage.getItem(key)
  try {
    return JSON.parse(window.localStorage.getItem(key) as string)
  }
  catch (error) {
    return value
  }
}

/**
 * @description 存储localStorage
 * @param {string} key Storage名称
 * @param {*} value Storage值
 * @returns {void}
 */
export function localSet(key: string, value: any) {
  window.localStorage.setItem(key, JSON.stringify(value))
}

/**
 * @description 清除localStorage
 * @param {string} key Storage名称
 * @returns {void}
 */
export function localRemove(key: string) {
  window.localStorage.removeItem(key)
}

/**
 * @description 清除所有localStorage
 * @returns {void}
 */
export function localClear() {
  window.localStorage.clear()
}

/**
 * @description 生成唯一 uuid
 * @returns {string} 返回生成的 uuid
 */
export function generateUUID() {
  let uuid = ''
  for (let i = 0; i < 32; i++) {
    const random = (Math.random() * 16) | 0
    if (i === 8 || i === 12 || i === 16 || i === 20)
      uuid += '-'
    uuid += (i === 12 ? 4 : i === 16 ? (random & 3) | 8 : random).toString(16)
  }
  return uuid
}

/**
 * 判断两个对象是否相同
 * @param {object} a 要比较的对象一
 * @param {object} b 要比较的对象二
 * @returns {boolean} 相同返回 true，反之 false
 */
export function isObjectValueEqual(a: { [key: string]: any }, b: { [key: string]: any }) {
  if (!a || !b)
    return false
  const aProps = Object.getOwnPropertyNames(a)
  const bProps = Object.getOwnPropertyNames(b)
  if (aProps.length !== bProps.length)
    return false
  for (let i = 0; i < aProps.length; i++) {
    const propName = aProps[i]
    const propA = a[propName]
    const propB = b[propName]
    if (!Object.prototype.hasOwnProperty.call(b, propName))
      return false
    if (propA instanceof Object) {
      if (!isObjectValueEqual(propA, propB))
        return false
    }
    else if (propA !== propB) {
      return false
    }
  }
  return true
}

/**
 * @description 生成随机数
 * @param {number} min 最小值
 * @param {number} max 最大值
 * @returns {number} 返回生成的随机数
 */
export function randomNum(min: number, max: number): number {
  return Math.floor(Math.random() * (min - max) + max)
}

/**
 * @description: 判断值是否未某个类型
 */
export function isType(val: unknown, type: string) {
  return Object.prototype.toString.call(val) === `[object ${type}]`
}

// 简单深复制
export function deepClone(obj: any) {
  if (obj === null)
    return null // null 的情况
  if (obj instanceof RegExp)
    return new RegExp(obj) // 正则表达式的情况
  if (obj instanceof Date)
    return new Date(obj) // 日期对象的情况
  if (obj instanceof Promise)
    return obj

  if (typeof obj != 'object')
    return obj

  // eslint-disable-next-line no-proto,no-restricted-properties
  const newObj = new obj.__proto__.constructor()
  for (const key in obj)
    newObj[key] = deepClone(obj[key])

  return newObj
}
/**
 * @description: 根据权限列表过滤菜单
 */
export function fitlerRouters(
  permissions: PermissionType[],
  routes: RouteRecordRaw[],
  map: any,
): RouteRecordRaw[] {
  const copyRoutes = deepClone(routes)
  return copyRoutes.filter((route: RouteRecordRaw) => {
    if (['/', '/home'].includes(route.path)) {
      if (route.children)
        route.children = fitlerRouters(permissions, route.children, map)

      return true
    }
    const code = map[route.path]
    const result = permissions.some(per => per.functionCode === code)
    if (result && route.children)
      route.children = fitlerRouters(permissions, route.children, map)

    return result
  })
}
/**
 * @description: 根据path找到对应路由
 */
export function findRouteConfig(
  routes: RouteRecordRaw[],
  path: string,
): RouteRecordRaw | undefined {
  let item
  for (let i = 0; i < routes.length; i++) {
    const route = routes[i]
    if (route.path === path) {
      item = route
      return item
    }
    else if (route.children) {
      item = findRouteConfig(route.children, path)
      if (item)
        return item
    }
  }
  return item
}

export function getVariableName(title: string) {
  return `__PRODUCTION__${strToHex(title) || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '')
}

export function strToHex(str: string) {
  const result: string[] = []
  for (let i = 0; i < str.length; ++i) {
    const hex = str.charCodeAt(i).toString(16)
    result.push((`000${hex}`).slice(-4))
  }
  return result.join('').toUpperCase()
}
